GtkEntry: add a "tabs" property for setting a PangoTabArray in the layout.
authorAndrew Walton <awalton@gnome.org>
Thu, 15 Aug 2013 18:34:31 +0000 (11:34 -0700)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 19 Aug 2013 17:43:32 +0000 (13:43 -0400)
I'm currently working on porting view::FieldEntry (from libview) to C for use in
upstream GTK+. FieldEntry is a widget which allows users to enter structured
text such as IPv4 addresses or serial numbers. The way that FieldEntry
delineates the fields within the entry is with tabstops, using PangoTabArray
entries to precisely position the fields and delimiters. Because GtkEntry
rebuilds its internal PangoLayout fairly frequently, this requires a property in
the entry that will set the tabs on the layout whenever that happens. This API
looks very similar to one in GtkTextView.

Patch by David Trowbridge <trowbrds@gmail.com>. Updated for Gtk+ 3.10.

https://bugzilla.gnome.org/show_bug.cgi?id=697399

docs/reference/gtk/gtk3-sections.txt
gtk/gtkentry.c
gtk/gtkentry.h

index 7f3d6148383efc231e12e468a32753504b6c2020..73d2b7fe0cf2e2b81268d3b7121673e7c0262b91 100644 (file)
@@ -1139,6 +1139,8 @@ gtk_entry_get_progress_pulse_step
 gtk_entry_progress_pulse
 gtk_entry_im_context_filter_keypress
 gtk_entry_reset_im_context
+gtk_entry_get_tabs
+gtk_entry_set_tabs
 GtkEntryIconPosition
 gtk_entry_set_icon_from_pixbuf
 gtk_entry_set_icon_from_stock
index 8c32bd07f195040756079fb18c728be3f44a2594..0a2c96b9740a7bf99ae00d1a64552ae22723623d 100644 (file)
@@ -149,6 +149,7 @@ struct _GtkEntryPrivate
 
   PangoLayout           *cached_layout;
   PangoAttrList         *attrs;
+  PangoTabArray         *tabs;
 
   gchar        *im_module;
 
@@ -319,7 +320,8 @@ enum {
   PROP_INPUT_PURPOSE,
   PROP_INPUT_HINTS,
   PROP_ATTRIBUTES,
-  PROP_POPULATE_ALL
+  PROP_POPULATE_ALL,
+  PROP_TABS
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -1450,7 +1452,21 @@ gtk_entry_class_init (GtkEntryClass *class)
                                                          P_("Whether to emit ::populate-popup for touch popups"),
                                                          FALSE,
                                                          GTK_PARAM_READWRITE));
-  
+  /**
+   * GtkEntry::tabs:
+   *
+   * A list of tabstops to apply to the text of the entry.
+   *
+   * Since: 3.8
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_TABS,
+                                   g_param_spec_boxed ("tabs",
+                                                       P_("Tabs"),
+                                                       P_("A list of tabstop locations to apply to the text of the entry"),
+                                                       PANGO_TYPE_TAB_ARRAY,
+                                                       GTK_PARAM_READWRITE));
+
   /**
    * GtkEntry:icon-prelight:
    *
@@ -2288,6 +2304,10 @@ gtk_entry_set_property (GObject         *object,
       entry->priv->populate_all = g_value_get_boolean (value);
       break;
 
+    case PROP_TABS:
+      gtk_entry_set_tabs (entry, g_value_get_boxed (value));
+      break
+
     case PROP_SCROLL_OFFSET:
     case PROP_CURSOR_POSITION:
     default:
@@ -2532,6 +2552,10 @@ gtk_entry_get_property (GObject         *object,
       g_value_set_boolean (value, priv->populate_all);
       break;
 
+    case PROP_TABS:
+      g_value_set_boxed (value, priv->tabs);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2886,6 +2910,9 @@ gtk_entry_finalize (GObject *object)
   g_free (priv->placeholder_text);
   g_free (priv->im_module);
 
+  if (priv->tabs)
+    pango_tab_array_free (priv->tabs);
+
   G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
 }
 
@@ -6079,6 +6106,9 @@ gtk_entry_create_layout (GtkEntry *entry,
       
   pango_layout_set_attributes (layout, tmp_attrs);
 
+  if (priv->tabs)
+    pango_layout_set_tabs (layout, priv->tabs);
+
   g_free (preedit_string);
   g_free (display);
 
@@ -10532,3 +10562,55 @@ gtk_entry_get_attributes (GtkEntry *entry)
   return entry->priv->attrs;
 }
 
+/**
+ * gtk_entry_set_tabs:
+ * @entry: a #GtkEntry
+ * @tabs: a #PangoTabArray
+ *
+ * Sets a #PangoTabArray; the tabstops in the array are applied to the entry
+ * text.
+ *
+ * Since: 3.10
+ */
+
+void
+gtk_entry_set_tabs (GtkEntry      *entry,
+                    PangoTabArray *tabs)
+{
+  GtkEntryPrivate *priv;
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  priv = entry->priv;
+  if (priv->tabs)
+    pango_tab_array_free(priv->tabs);
+
+  if (tabs)
+    priv->tabs = pango_tab_array_copy (tabs);
+  else
+    priv->tabs = NULL;
+
+  g_object_notify (G_OBJECT (entry), "tabs");
+
+  gtk_entry_recompute (entry);
+  gtk_widget_queue_resize (GTK_WIDGET (entry));
+}
+
+/**
+ * gtk_entry_get_tabs:
+ * @entry: a #GtkEntry
+ *
+ * Gets the tabstops that were set on the entry using gtk_entry_set_tabs(), if
+ * any.
+ *
+ * Return value: (transfer none): the tabstops, or %NULL if none was set.
+ *
+ * Since: 3.10
+ */
+
+PangoTabArray *
+gtk_entry_get_tabs (GtkEntry *entry)
+{
+  g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
+
+  return entry->priv->tabs;
+}
index 3ca818bc0c1d541de82ae351f303bfd40171fa07..5bb79d230063a1aed514a5645d5c9cb85d8c827d 100644 (file)
@@ -361,6 +361,13 @@ void            gtk_entry_set_attributes                     (GtkEntry
 GDK_AVAILABLE_IN_3_6
 PangoAttrList  *gtk_entry_get_attributes                     (GtkEntry             *entry);
 
+GDK_AVAILABLE_IN_3_10
+void            gtk_entry_set_tabs                           (GtkEntry             *entry,
+                                                              PangoTabArray        *tabs);
+
+GDK_AVAILABLE_IN_3_10
+PangoTabArray  *gtk_entry_get_tabs                           (GtkEntry             *entry);
+
 G_END_DECLS
 
 #endif /* __GTK_ENTRY_H__ */